using System;
using System.Text;
using Org.BouncyCastle.Crypto.Engines;
using Org.BouncyCastle.Crypto.Modes;
using Org.BouncyCastle.Crypto.Paddings;
using Org.BouncyCastle.Crypto.Parameters;

public class SM4Util
{
    private readonly byte[] _key;
    private readonly bool _forEncryption;

    /// <summary>
    /// SM4加解密工具
    /// </summary>
    /// <param name="hexKey">16进制字符串形式的密钥(32个字符，16字节)</param>
    /// <param name="forEncryption">true表示加密，false表示解密</param>
    public SM4Util(string hexKey, bool forEncryption = true)
    {
        if (hexKey.Length != 32)
            throw new ArgumentException("SM4密钥长度必须为32个字符(16字节)");

        _key = HexStringToByteArray(hexKey);
        _forEncryption = forEncryption;
    }

    /// <summary>
    /// 加密字符串
    /// </summary>
    /// <param name="plainText">明文</param>
    /// <returns>16进制大写字符串形式的密文</returns>
    public string Encrypt(string plainText)
    {
        byte[] inputBytes = Encoding.UTF8.GetBytes(plainText);
        byte[] encryptedBytes = Process(inputBytes);
        return ByteArrayToHexString(encryptedBytes).ToUpper();
    }

    /// <summary>
    /// 解密字符串
    /// </summary>
    /// <param name="hexCipherText">16进制字符串形式的密文</param>
    /// <returns>明文</returns>
    public string Decrypt(string hexCipherText)
    {
        byte[] inputBytes = HexStringToByteArray(hexCipherText);
        byte[] decryptedBytes = Process(inputBytes);
        return Encoding.UTF8.GetString(decryptedBytes).TrimEnd('\0');
    }

    private byte[] Process(byte[] input)
    {
        // 创建SM4引擎
        var engine = new SM4Engine();
        
        // 使用ECB模式
        var cipher = new PaddedBufferedBlockCipher(engine, new Pkcs7Padding());
        
        // 初始化密钥参数
        var keyParam = new KeyParameter(_key);
        cipher.Init(_forEncryption, keyParam);

        // 处理数据
        byte[] output = new byte[cipher.GetOutputSize(input.Length)];
        int len = cipher.ProcessBytes(input, 0, input.Length, output, 0);
        cipher.DoFinal(output, len);

        return output;
    }

    /// <summary>
    /// 16进制字符串转字节数组
    /// </summary>
    private static byte[] HexStringToByteArray(string hex)
    {
        if (hex.Length % 2 != 0)
            throw new ArgumentException("16进制字符串长度必须是偶数");

        byte[] bytes = new byte[hex.Length / 2];
        for (int i = 0; i < hex.Length; i += 2)
            bytes[i / 2] = Convert.ToByte(hex.Substring(i, 2), 16);
        
        return bytes;
    }

    /// <summary>
    /// 字节数组转16进制字符串
    /// </summary>
    private static string ByteArrayToHexString(byte[] bytes)
    {
        StringBuilder hex = new StringBuilder(bytes.Length * 2);
        foreach (byte b in bytes)
            hex.AppendFormat("{0:x2}", b);
        
        return hex.ToString();
    }
}